package ui.panel;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.JButton;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

import session.Session;
import storage.manager.DatabaseManager;
import ui.MainFrame;
import ui.excute.UICommandProcessor;

public class DatabaseTreePanel extends JPanel {
    private JTree tree;
    private DefaultTreeModel treeModel;
    private DefaultMutableTreeNode rootNode;
    private String currentDatabase;

    public DatabaseTreePanel() {
        rootNode = new DefaultMutableTreeNode("数据库");
        treeModel = new DefaultTreeModel(rootNode);
        tree = new JTree(treeModel);
        tree.setShowsRootHandles(true);
        tree.setRootVisible(true);

        // 设置自定义渲染器，为数据库和表添加不同图标
        tree.setCellRenderer(new DefaultTreeCellRenderer() {
            @Override
            public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded,
                                                          boolean leaf, int row, boolean hasFocus) {
                super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);

                DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
                switch (node.getLevel()) {
                    case 1: // 用户节点或授权数据库节点
                        if (node.getUserObject().toString().equals("授权数据库")) {
                            setIcon(UIManager.getIcon("FileView.hardDriveIcon"));
                        } else {
                            setIcon(UIManager.getIcon("FileView.computerIcon"));
                        }
                        break;
                    case 2: // 数据库所有者节点或数据库节点
                        if ( ((DefaultMutableTreeNode)node.getParent()).getUserObject().toString().equals("授权数据库")) {
                            setIcon(UIManager.getIcon("FileView.computerIcon")); // 所有者节点
                        } else {
                            setIcon(UIManager.getIcon("FileView.directoryIcon")); // 数据库节点
                        }
                        break;
                    case 3: // 数据库节点(授权数据库下)或表节点
                        if (((DefaultMutableTreeNode)node.getParent().getParent()).getUserObject().toString().equals("授权数据库")) {
                            setIcon(UIManager.getIcon("FileView.directoryIcon")); // 授权数据库下的数据库节点
                        } else {
                            setIcon(UIManager.getIcon("FileView.fileIcon")); // 表节点
                        }
                        break;
                    case 4: // 表节点(授权数据库下)
                        setIcon(UIManager.getIcon("FileView.fileIcon"));
                        break;
                }
                return this;
            }
        });


        // 创建刷新按钮
        JButton refreshButton = new JButton("刷新树结构");
        refreshButton.addActionListener(e -> refreshTree());

        // 使用 BorderLayout 布局
        setLayout(new BorderLayout());

        // 创建一个面板来放置按钮
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(refreshButton);

        // 将按钮面板添加到北部
        add(buttonPanel, BorderLayout.NORTH);

        // 将树添加到中部
        add(new JScrollPane(tree), BorderLayout.CENTER);

        // 添加数据库变更监听器
        DatabaseManager.addDatabaseChangeListener(this::refreshTree);

        refreshTree();
        initListeners();
    }

    public void refreshTree() {
        SwingUtilities.invokeLater(() -> {
            rootNode.removeAllChildren();

            try {
                // 获取当前会话
                Session currentSession = Session.getCurrentSession();
                if (currentSession == null) {
                    System.err.println("[DatabaseTreePanel] 刷新失败: 没有活动会话");
                    return;
                }

                String currentUser = currentSession.getUsername();
                if (currentUser == null) {
                    System.err.println("[DatabaseTreePanel] 刷新失败: 无法获取当前用户");
                    return;
                }

                System.out.println("[DatabaseTreePanel] 开始刷新数据库树... 当前用户: " + currentUser);

                // 获取所有可访问数据库
                List<String> allDatabases = UICommandProcessor.getAllDatabases();
                System.out.println("[DatabaseTreePanel] 获取到 " + allDatabases.size() + " 个可访问数据库");

                // 创建用户节点
                DefaultMutableTreeNode currentUserNode = new DefaultMutableTreeNode(currentUser + " (我的数据库)");
                rootNode.add(currentUserNode);

                // 创建授权数据库节点组
                DefaultMutableTreeNode authorizedDbsNode = new DefaultMutableTreeNode("授权数据库");
                boolean hasAuthorizedDbs = false;

                // 按所有者分组数据库
                Map<String, List<String>> ownerToDbs = new HashMap<>();
                for (String fullDbNameINFO : allDatabases) {
                    String fullDbName = UICommandProcessor.splitDatabaseInfoLine(fullDbNameINFO)[0]; // 分离数据库名称和时间信息
                    String[] parts = fullDbName.split("\\.");
                    if (parts.length >= 2) {
                        String owner = parts[0];
                        String dbName = parts[1];
                        ownerToDbs.computeIfAbsent(owner, k -> new ArrayList<>()).add(dbName);
                    }
                }

                // 先添加当前用户的数据库
                List<String> myDatabases = ownerToDbs.getOrDefault(currentUser, new ArrayList<>());
                System.out.println("[DatabaseTreePanel] 当前用户拥有 " + myDatabases.size() + " 个数据库");

                for (String dbName : myDatabases) {
                    DefaultMutableTreeNode dbNode = new DefaultMutableTreeNode(dbName);
                    currentUserNode.add(dbNode);

                    // 尝试获取表列表
                    try {
                        String fullDbName = currentUser + "." + dbName;
                        System.out.println("[DatabaseTreePanel] 正在获取数据库 '" + fullDbName + "' 的表...");

                        List<String> tables = UICommandProcessor.getTables(fullDbName);
                        System.out.println("[DatabaseTreePanel] 数据库 '" + fullDbName + "' 有 " + tables.size() + " 个表");

                        for (String tableName : tables) {
                            DefaultMutableTreeNode tableNode = new DefaultMutableTreeNode(tableName);
                            dbNode.add(tableNode);
                        }
                    } catch (Exception e) {
                        System.err.println("[DatabaseTreePanel] 获取表失败: " + dbName + ", 错误: " + e.getMessage());
                        e.printStackTrace();
                    }
                }

                // 然后添加其他用户授权的数据库
                for (Map.Entry<String, List<String>> entry : ownerToDbs.entrySet()) {
                    String owner = entry.getKey();
                    if (owner.equals(currentUser)) continue; // 跳过自己的数据库

                    DefaultMutableTreeNode ownerNode = new DefaultMutableTreeNode(owner);
                    boolean hasOwnerDbs = false;

                    for (String dbName : entry.getValue()) {
                        DefaultMutableTreeNode dbNode = new DefaultMutableTreeNode(dbName);
                        ownerNode.add(dbNode);
                        hasOwnerDbs = true;

                        // 尝试获取表列表 - 改进的错误处理
                        try {
                            String fullDbName = owner + "." + dbName;
                            System.out.println("[DatabaseTreePanel] 正在获取授权数据库 '" + fullDbName + "' 的表...");

                            List<String> tables = UICommandProcessor.getTables(fullDbName);
                            System.out.println("[DatabaseTreePanel] 授权数据库 '" + fullDbName + "' 有 " + tables.size() + " 个表");

                            for (String tableName : tables) {
                                DefaultMutableTreeNode tableNode = new DefaultMutableTreeNode(tableName);
                                dbNode.add(tableNode);
                            }
                        } catch (Exception e) {
                            System.err.println("[DatabaseTreePanel] 获取授权数据库表失败: " + owner + "." + dbName + ", 错误: " + e.getMessage());
                        }
                    }

                    if (hasOwnerDbs) {
                        authorizedDbsNode.add(ownerNode);
                        hasAuthorizedDbs = true;
                    }
                }

                if (hasAuthorizedDbs) {
                    rootNode.add(authorizedDbsNode);
                }

                treeModel.reload();
                expandAllNodes();
                System.out.println("[DatabaseTreePanel] 数据库树刷新完成");
            } catch (Exception e) {
                System.err.println("[DatabaseTreePanel] 刷新树结构时发生错误: " + e.getMessage());
                e.printStackTrace();
            }
        });
    }

    public void setCurrentDatabase(String dbName) {
        this.currentDatabase = dbName;
        TreePath path = findNodePath(dbName);
        if (path != null) {
            tree.setSelectionPath(path);
            tree.scrollPathToVisible(path);
        }
    }

    private TreePath findNodePath(String dbName) {
        Enumeration<TreeNode> owners = rootNode.children();
        while (owners.hasMoreElements()) {
            DefaultMutableTreeNode ownerNode = (DefaultMutableTreeNode) owners.nextElement();
            Enumeration<TreeNode> children = ownerNode.children();
            while (children.hasMoreElements()) {
                TreeNode child = children.nextElement();
                DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) child;

                // 处理我的数据库下的数据库节点
                if (childNode.getUserObject().toString().equals(dbName)) {
                    return new TreePath(childNode.getPath());
                }

                // 处理授权数据库下的所有者节点
                if (childNode.getUserObject().toString().equals("授权数据库")) {
                    Enumeration<TreeNode> ownerNodes = childNode.children();
                    while (ownerNodes.hasMoreElements()) {
                        TreeNode owner = ownerNodes.nextElement();
                        DefaultMutableTreeNode ownerInAuth = (DefaultMutableTreeNode) owner;
                        Enumeration<TreeNode> authDbs = ownerInAuth.children();
                        while (authDbs.hasMoreElements()) {
                            TreeNode authDb = authDbs.nextElement();
                            DefaultMutableTreeNode authDbNode = (DefaultMutableTreeNode) authDb;
                            if (authDbNode.getUserObject().toString().equals(dbName)) {
                                return new TreePath(authDbNode.getPath());
                            }
                        }
                    }
                }
            }
        }
        return null;
    }


    private void initListeners() {
        tree.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                if (SwingUtilities.isRightMouseButton(e)) {
                    TreePath path = tree.getPathForLocation(e.getX(), e.getY());
                    if (path == null) return;
                    tree.setSelectionPath(path);
                    DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
                    int level = node.getLevel();
                    JPopupMenu popup = new JPopupMenu();

                    // 处理数据库节点 (可能是Level 2或Level 3，取决于是否在授权数据库下)
                    if ((level == 2 && !((DefaultMutableTreeNode)node.getParent()).getUserObject().toString().equals("授权数据库")) ||
                        (level == 3 && ((DefaultMutableTreeNode)node.getParent().getParent()).getUserObject().toString().equals("授权数据库"))) {
                        String ownerWithLabel = ((DefaultMutableTreeNode) node.getParent()).getUserObject().toString();
                        // 移除可能包含的标签部分 "(我的数据库)"
                        String owner = ownerWithLabel.contains(" (") ?
                                       ownerWithLabel.substring(0, ownerWithLabel.indexOf(" (")) :
                                       ownerWithLabel;
                        String dbName = node.getUserObject().toString();
                        String fullDbName = owner + "." + dbName;

                        System.out.println("[DatabaseTreePanel] 准备切换数据库: " + fullDbName);


                        JMenuItem useItem = new JMenuItem("切换数据库");
                        useItem.addActionListener(ae -> {
                            if (UICommandProcessor.useDatabase(fullDbName)) {
                                setCurrentDatabase(fullDbName);
                                refreshTree(); // 新增：手动刷新树结构
                                if (SwingUtilities.getWindowAncestor(DatabaseTreePanel.this) instanceof MainFrame) {
                                    ((MainFrame) SwingUtilities.getWindowAncestor(DatabaseTreePanel.this)).updateStatusBar();
                                }
                            }
                        });

                        JMenuItem deleteItem = new JMenuItem("删除数据库");
                        deleteItem.addActionListener(ae -> {
                            int confirm = JOptionPane.showConfirmDialog(
                                    DatabaseTreePanel.this,
                                    "确定要删除数据库 " + fullDbName + " 吗？",
                                    "确认",
                                    JOptionPane.YES_NO_OPTION);

                            if (confirm == JOptionPane.YES_OPTION) {
                                if (UICommandProcessor.dropDatabase(fullDbName) == 1) {
                                    JOptionPane.showMessageDialog(
                                            DatabaseTreePanel.this,
                                            "数据库 " + fullDbName + " 删除成功",
                                            "成功",
                                            JOptionPane.INFORMATION_MESSAGE);
                                    refreshTree();
                                } else {
                                    JOptionPane.showMessageDialog(
                                            DatabaseTreePanel.this,
                                            "数据库 " + fullDbName + " 删除失败",
                                            "错误",
                                            JOptionPane.ERROR_MESSAGE);
                                }
                            }
                        });

                        popup.add(useItem);
                        // 只有自己的数据库才能删除
                        if (level == 2) {
                            popup.add(deleteItem);
                        }
                        popup.add(new JMenuItem("刷新")).addActionListener(ae -> refreshTree());

                        popup.show(tree, e.getX(), e.getY());
                    }

                    // 处理表节点 (可能是Level 3或Level 4，取决于是否在授权数据库下)
                    else if ((level == 3 && !((DefaultMutableTreeNode)node.getParent().getParent()).getUserObject().toString().equals("授权数据库")) ||
                             (level == 4 && ((DefaultMutableTreeNode)node.getParent().getParent().getParent()).getUserObject().toString().equals("授权数据库"))) {
                        String tableName = node.getUserObject().toString();
                        String dbName, ownerWithLabel;

                        if (level == 3) {
                            // 我的数据库下的表节点
                            dbName = ((DefaultMutableTreeNode) node.getParent()).getUserObject().toString();
                            ownerWithLabel = ((DefaultMutableTreeNode) node.getParent().getParent()).getUserObject().toString();
                        } else {
                            // 授权数据库下的表节点
                            dbName = ((DefaultMutableTreeNode) node.getParent().getParent()).getUserObject().toString();
                            ownerWithLabel = ((DefaultMutableTreeNode) node.getParent().getParent().getParent()).getUserObject().toString();
                        }
                        // 移除可能包含的标签部分 "(我的数据库)"
                        String owner = ownerWithLabel.contains(" (") ?
                                      ownerWithLabel.substring(0, ownerWithLabel.indexOf(" (")) :
                                      ownerWithLabel;
                        String fullDbName = owner + "." + dbName;

                        System.out.println("[DatabaseTreePanel] 准备操作表: " + fullDbName + "." + tableName);

                        JMenuItem viewStructure = new JMenuItem("查看表结构");
                        viewStructure.addActionListener(ae -> {
                            System.out.println("[DBTreePanel-ViewStructure] Action started.");
                            MainFrame mainFrame = (MainFrame) SwingUtilities.getWindowAncestor(DatabaseTreePanel.this);

                            if (mainFrame != null) {
                                System.out.println("[DBTreePanel-ViewStructure] MainFrame instance obtained.");
                                System.out.println("[DBTreePanel-ViewStructure] Extracted Owner: " + owner + ", DB: " + dbName + ", Table: " + tableName);

                                // 先取消当前数据库选择
                                UICommandProcessor.process("unuse");

                                // 然后切换到正确的数据库
                                if (UICommandProcessor.useDatabase(fullDbName)) {
                                    System.out.println("[DBTreePanel-ViewStructure] Successfully switched to database: " + fullDbName);

                                    String descCommand = "DESCRIBE " + tableName;
                                    System.out.println("[DBTreePanel-ViewStructure] Preparing to execute: " + descCommand);
                                    try {
                                        // 确保在UI线程中执行命令
                                        SwingUtilities.invokeLater(() -> {
                                            try {
                                                mainFrame.executeCommand(descCommand);
                                                System.out.println("[DBTreePanel-ViewStructure] Successfully executed: " + descCommand);
                                            } catch (Throwable t) {
                                                System.err.println("[DBTreePanel-ViewStructure] Exception/Error during DESCRIBE command: " + t.getMessage());
                                                t.printStackTrace();
                                            }
                                        });
                                    } catch (Throwable t) {
                                        System.err.println("[DBTreePanel-ViewStructure] Exception/Error creating invokeLater: " + t.getMessage());
                                        t.printStackTrace();
                                    }
                                } else {
                                    System.err.println("[DBTreePanel-ViewStructure] Failed to switch to database: " + fullDbName);
                                    JOptionPane.showMessageDialog(
                                        mainFrame,
                                        "无法切换到数据库: " + fullDbName + "\n可能没有访问权限或数据库不存在。",
                                        "数据库切换失败",
                                        JOptionPane.ERROR_MESSAGE
                                    );
                                }
                            } else {
                                System.err.println("[DBTreePanel-ViewStructure] MainFrame instance is null. Cannot execute commands.");
                            }
                            System.out.println("[DBTreePanel-ViewStructure] Action finished.");
                        });

                        JMenuItem queryTable = new JMenuItem("查询数据");
                        queryTable.addActionListener(ae -> {
                            MainFrame mainFrame = (MainFrame) SwingUtilities.getWindowAncestor(DatabaseTreePanel.this);
                            if (mainFrame != null) {
                                System.out.println("[DBTreePanel-QueryTable] Action started.");
                                System.out.println("[DBTreePanel-QueryTable] Extracted Owner: " + owner + ", DB: " + dbName + ", Table: " + tableName);

                                // 先取消当前数据库选择
                                UICommandProcessor.process("unuse");

                                // 然后切换到正确的数据库
                                if (UICommandProcessor.useDatabase(fullDbName)) {
                                    System.out.println("[DBTreePanel-QueryTable] Successfully switched to database: " + fullDbName);
                                    setCurrentDatabase(fullDbName);
                                    refreshTree(); // 新增：手动刷新树结构

                                    String queryCommand = "SELECT * FROM " + tableName;
                                    System.out.println("[DBTreePanel-QueryTable] Executing: " + queryCommand);
                                    // 确保在UI线程中执行命令
                                    SwingUtilities.invokeLater(() -> {
                                        try {
                                            mainFrame.executeCommand(queryCommand);
                                            System.out.println("[DBTreePanel-QueryTable] Successfully executed: " + queryCommand);
                                        } catch (Throwable t) {
                                            System.err.println("[DBTreePanel-QueryTable] Exception/Error during SELECT command: " + t.getMessage());
                                            t.printStackTrace();
                                        }
                                    });
                                } else {
                                    System.err.println("[DBTreePanel-QueryTable] Failed to switch to database: " + fullDbName);
                                    JOptionPane.showMessageDialog(
                                        mainFrame,
                                        "无法切换到数据库: " + fullDbName + "\n可能没有访问权限或数据库不存在。",
                                        "数据库切换失败",
                                        JOptionPane.ERROR_MESSAGE
                                    );
                                }
                            }
                        });

                        popup.add(viewStructure);
                        popup.add(queryTable);
                    }

                    popup.show(tree, e.getX(), e.getY());

                }
            }

            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton(e)) {
                    System.out.println("[DBTreePanel-DoubleClick] Detected double-click.");
                    TreePath path = tree.getPathForLocation(e.getX(), e.getY());
                    if (path == null) {
                        System.out.println("[DBTreePanel-DoubleClick] Path is null.");
                        return;
                    }

                    DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
                    System.out.println("[DBTreePanel-DoubleClick] Clicked Node: '" + node.getUserObject() + "', Level: " + node.getLevel());

                    if (node.getLevel() == 3) { // Assuming Level 3 is a Table node
                        String tableName = node.getUserObject().toString();
                        DefaultMutableTreeNode dbNode = (DefaultMutableTreeNode) node.getParent();
                        String dbName = dbNode.getUserObject().toString();
                        DefaultMutableTreeNode ownerNode = (DefaultMutableTreeNode) dbNode.getParent();
                        String ownerWithLabel = ownerNode.getUserObject().toString();
                        // 移除可能包含的标签部分 "(我的数据库)"
                        String owner = ownerWithLabel.contains(" (") ?
                                      ownerWithLabel.substring(0, ownerWithLabel.indexOf(" (")) :
                                      ownerWithLabel;
                        String fullDbName = owner + "." + dbName;

                        System.out.println("[DBTreePanel-DoubleClick] Extracted Owner: '" + owner + "', DB: '" + dbName + "', Table: '" + tableName + "'");

                        Object windowAncestor = SwingUtilities.getWindowAncestor(DatabaseTreePanel.this);
                        if (windowAncestor instanceof MainFrame) {
                            MainFrame mainFrame = (MainFrame) windowAncestor;

                            // 首先使用UICommandProcessor直接切换数据库，这样可以避免SQL语法解析问题
                            if (UICommandProcessor.useDatabase(fullDbName)) {
                                System.out.println("[DBTreePanel-DoubleClick] Successfully switched to database: " + fullDbName);

                                // 然后执行DESCRIBE命令
                                String descTableCommand = "DESCRIBE " + tableName;
                                System.out.println("[DBTreePanel-DoubleClick] Executing: " + descTableCommand);
                                mainFrame.executeCommand(descTableCommand);
                            } else {
                                System.err.println("[DBTreePanel-DoubleClick] Failed to switch to database: " + fullDbName);
                                JOptionPane.showMessageDialog(
                                    mainFrame, 
                                    "无法切换到数据库: " + fullDbName + "\n可能没有访问权限或数据库不存在。", 
                                    "数据库切换失败", 
                                    JOptionPane.ERROR_MESSAGE
                                );
                            }
                        } else {
                            System.out.println("[DBTreePanel-DoubleClick] MainFrame not found. Ancestor is: " + (windowAncestor != null ? windowAncestor.getClass().getName() : "null"));
                        }
                    } else {
                        System.out.println("[DBTreePanel-DoubleClick] Clicked node is not a table node (expected level 3). Actual Level: " + node.getLevel());
                    }
                } else if (e.getClickCount() == 1 && SwingUtilities.isLeftMouseButton(e)) {
                    TreePath path = tree.getPathForLocation(e.getX(), e.getY());
                    if (path == null) {
                        System.out.println("[DBTreePanel-SingleClick] Path is null.");
                        return;
                    }
                    DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent();
                    System.out.println("[DBTreePanel-SingleClick] Clicked Node: '" + node.getUserObject() + "', Level: " + node.getLevel() + ". No command executed.");
                }
            }
        });
    }

    public JTree getTree() {
        return tree;
    }

    /**
     * 展开树中的所有节点
     */
    private void expandAllNodes() {
        for (int i = 0; i < tree.getRowCount(); i++) {
            tree.expandRow(i);
        }
    }
}